package org.jmh.gift.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.jmh.gift.constants.GiftConstants;
import org.jmh.gift.domain.GoodsSpu;
import org.jmh.gift.dto.OffsaleDto;
import org.jmh.gift.dto.OnsaleDto;
import org.jmh.gift.enums.SystemErrorCode;
import org.jmh.gift.exception.BusinessException;
import org.jmh.gift.mapper.GoodsSpuMapper;
import org.jmh.gift.query.GoodsSpuQuery;
import org.jmh.gift.service.IGoodsSpuService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.jmh.gift.util.AjaxResult;
import org.jmh.gift.util.JMHAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * spu表 服务实现类
 * </p>
 *
 * @author lingfeng
 * @since 2024-07-30
 */
@Service
public class GoodsSpuServiceImpl extends ServiceImpl<GoodsSpuMapper, GoodsSpu> implements IGoodsSpuService {


    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private GoodsSpuMapper goodsSpuMapper;
    @Override
    public String onsale(List<Long> ids) {
        // id非空的校验
        JMHAssert.isNotNull(ids, SystemErrorCode.RESPONSE_CODE_400004);
        //状态校验
        Wrapper<GoodsSpu> wrapper = new EntityWrapper<GoodsSpu>()
                .in("id", ids)
                .and()
                .eq("state", 1).or().eq("state", 3);
        List<GoodsSpu> spus = goodsSpuMapper.selectList(
                wrapper
        );
        //发送测试消息
        String msg = "当前一共操作%s条数据,其中成功%s条数据,失败%s条数据";
        msg = String.format(msg,ids.size(),spus.size(),(ids.size() - spus.size()));


        //封装rocketmq所需数据消息
        List<OnsaleDto> OnsaleDtos = new ArrayList<>();
        for (GoodsSpu spu : spus) {
            OnsaleDto saleDto = new OnsaleDto();
            saleDto.setId(spu.getId());
            saleDto.setCover(spu.getCover());
            saleDto.setName(spu.getGoodsName());
            saleDto.setTenantId(spu.getTenantId());
            saleDto.setTenantName(spu.getTenantName());
            saleDto.setOnsaleTime(new Date());
            saleDto.setTypeId(spu.getCategoryId());
            saleDto.setTypeName("口红");
            saleDto.setBrandId(spu.getBrandId());
            saleDto.setBrandName("香奈儿");
            // 无
            saleDto.setCommentCount(0);
            saleDto.setSaleCount(0);
            saleDto.setSkuProperties("");
            saleDto.setSkuProperties("");
            //
            saleDto.setMaxPrice(spu.getHighPrice());
            saleDto.setMinPrice(spu.getLowPrice());

            OnsaleDtos.add(saleDto);
        }

        //保存文档-发送事务消息,由搜索服务消费消息保存文档
        if(OnsaleDtos.size() > 0){
            Message<List<OnsaleDto>> message = MessageBuilder.withPayload(OnsaleDtos).build();
            TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(
                    GiftConstants.GIFT_ONSALE_TX_PRODUCER_GROUP,
                    GiftConstants.GIFT_ONSALE_TX_TOPIC + ":" + GiftConstants.GIFT_ONSALE_TX_TAG,
                    message, null
            );
            System.out.println("事务消息发送的结果是"+sendResult);
            // 若事务消息或者本地事务失败,说明上架失败
            if(sendResult.getSendStatus() != SendStatus.SEND_OK ||
                    sendResult.getLocalTransactionState() != LocalTransactionState.COMMIT_MESSAGE){
                throw new BusinessException("上架失败!");
            }
        }

        return msg;
    }

    @Override
    public String offsale(List<Long> ids) {
        // 1 参数校验
        // 1.1 参数非空校验
        JMHAssert.isNotNull(ids, SystemErrorCode.RESPONSE_CODE_400004);
        // 1.2 状态校验 state(上架 下架 审核通过 审核失败)
        // 审核失败 -> 下架  -> 上架,审核失败的不能做下架
        List<GoodsSpu> spus = selectBatchIds(ids)
                .stream().filter(x -> x.getState() == 2).collect(Collectors.toList());
        //发送测试消息
        String msg = "当前一共操作%s条数据,其中成功%s条数据,失败%s条数据";
        msg = String.format(msg,ids.size(),spus.size(),(ids.size() - spus.size()));
        // 2 发送rocketmq事务消息
        //封装rocketmq所需数据消息
        List<OffsaleDto> OffsaleDtos = new ArrayList<>();
        for (GoodsSpu spu : spus) {
            OffsaleDto saleDto = new OffsaleDto();
            saleDto.setId(spu.getId());
            saleDto.setCover(spu.getCover());
            saleDto.setName(spu.getGoodsName());
            saleDto.setTenantId(spu.getTenantId());
            saleDto.setTenantName(spu.getTenantName());
            saleDto.setOffsaleTime(new Date());
            saleDto.setTypeId(spu.getCategoryId());
            saleDto.setTypeName("口红");
            saleDto.setBrandId(spu.getBrandId());
            saleDto.setBrandName("香奈儿");
            // 无
            saleDto.setCommentCount(0);
            saleDto.setSaleCount(0);
            saleDto.setSkuProperties("");
            saleDto.setSkuProperties("");
            //
            saleDto.setMaxPrice(spu.getHighPrice());
            saleDto.setMinPrice(spu.getLowPrice());

            OffsaleDtos.add(saleDto);
        }
        if(OffsaleDtos.size() > 0){
            Message<List<OffsaleDto>> message = MessageBuilder.withPayload(OffsaleDtos).build();
            TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(
                    GiftConstants.GIFT_OFFSALE_TX_PRODUCER_GROUP,
                    GiftConstants.GIFT_OFFSALE_TX_TOPIC + ":" + GiftConstants.GIFT_OFFSALE_TX_TAG,
                    message, null
            );
            System.out.println("事务消息发送的结果是"+sendResult);
            // 若事务消息或者本地事务失败,说明下架失败
            if(sendResult.getSendStatus() != SendStatus.SEND_OK ||
                    sendResult.getLocalTransactionState() != LocalTransactionState.COMMIT_MESSAGE){
                throw new BusinessException("下架失败!");
            }
        }

        return msg;
        // 本地事务:修改数据库状态=下架,添加下架时间  添加操作日志  删除详情页面
        // 搜索微服务,监听消息队列, 拿到消息以后,删除es中相关信息
    }

    @Override
    public AjaxResult executeOnsaleLocalTransactionOpr(List<OnsaleDto> spuOnsaleDtos) {
        //修改数据库状态为上架
        List<Long> spuIds = spuOnsaleDtos.stream()
                .map(OnsaleDto::getId)
                .collect(Collectors.toList());
        goodsSpuMapper.onOrOffSale(spuIds,2);
        //int i = 1/0;
        //保存上下架日志 @TODO
        //页面静态化 @TODO
        return AjaxResult.success();
    }



    @Override
    public Boolean checkExsitOnsaled(List<OnsaleDto> onsaleDtos) {
        List<Long> ids = onsaleDtos.stream().map(OnsaleDto::getId).collect(Collectors.toList());
        List<GoodsSpu> spus = goodsSpuMapper.selectList(
                new EntityWrapper<GoodsSpu>()
                        .in("id", ids)
                        .and()
                        .eq("state", 2)
        );
        return spus.size() > 0;
    }


    @Override
    public AjaxResult executeOffsaleLocalTransactionOpr(List<OffsaleDto> offsaleDtos) {
        //修改数据库状态为下架
        List<Long> ids = offsaleDtos.stream().map(OffsaleDto::getId).collect(Collectors.toList());
        // 1 修改数据库状态=下架,添加下架时间
        goodsSpuMapper.onOrOffSale(ids,3);
        //int i = 1/0;
        //保存上下架日志 @TODO
        //页面静态化 @TODO
        return AjaxResult.success();
    }

    @Override
    public Boolean checkExsitOffsaled(List<OffsaleDto> offsaleDtos) {
        List<Long> ids = offsaleDtos.stream().map(OffsaleDto::getId).collect(Collectors.toList());
        List<GoodsSpu> spus = goodsSpuMapper.selectList(
                new EntityWrapper<GoodsSpu>()
                        .in("id", ids)
                        .and()
                        .eq("state", 3)
        );
        return spus.size() > 0;
    }








}
